﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace JewelLibrary
{
     abstract class AbstractJewel
    {
        public abstract double Cost { get; set; }
        public abstract double Carat { get; set; }
        public abstract string Name { get; set; }
    }

     class Necklace
    {
        protected double cost;
        protected double carat;
        protected List<AbstractJewel> stones;

        public double Cost
        {
            get { return cost; }
            set { cost = value; }
        }
        public double Carat
        {
            get { return carat; }
            set { carat = value; }
        }

        public Necklace()
        {
            cost = 0;
            carat = 0;
            stones = new List<AbstractJewel>();
        }
        public string CountCaratAndCost(List <AbstractJewel> jlist, string requiredstones)
        {
            string[] ar = requiredstones.Split(',');
            for (int i = 0; i < ar.Length; i++)
            {
                try
                {
                    if ((i+1) % 2 != 0)
                    {
                        int type = 0;
                        Int32.TryParse(ar[i], out type);
                        int number = 0;
                        Int32.TryParse(ar[i+1], out number);
                        stones.Add(jlist[type]);
                        carat += jlist[type].Carat*number;
                        cost += jlist[type].Cost*number;
                    }
                }
                catch(Exception e)
                {
                    MessageBox.Show("Ошибка");
                    return "ОШИБКА";
                }
            }
            string result = "";
            result += carat.ToString() + ";" + cost.ToString();

            return result;

        }
    }

     abstract class Precious : AbstractJewel
    {
         public abstract string Luster { get; set; }
    }

     abstract class NotPrecious : AbstractJewel
    {
         public abstract string Origin { get; set; }
    }

     class Ruby : Precious
    {
        private double cost;
        private double carat;
        private string name;
        private string luster;

        public override double Cost
        {
            get { return cost; }
            set { cost = value; }
        }
        public override double Carat
        {
            get { return carat; }
            set { carat = value; }
        }
        public override string Name
        {
            get { return name; }
            set { name = value; }
        }
        public override string Luster
        {
            get { return luster; }
            set { luster = value; }
        }

        public Ruby(double cost, double carat, string name, string luster)
        {
            this.carat = carat;
            this.cost = cost;
            this.name = name;
            this.luster = luster;
        }
    }

     class Diamond : Precious
    {
        private double cost;
        private double carat;
        private string name;
        private string luster;

        public override double Cost
        {
            get { return cost; }
            set { cost = value; }
        }
        public override double Carat
        {
            get { return carat; }
            set { carat = value; }
        }
        public override string Name
        {
            get { return name; }
            set { name = value; }
        }
        public override string Luster
        {
            get { return luster; }
            set { luster = value; }
        }
        public Diamond(double cost, double carat, string name, string luster)
        {
            this.carat = carat;
            this.cost = cost;
            this.name = name;
            this.luster = luster;
        }
    }

     class Emerald : Precious
    {
        private double cost;
        private double carat;
        private string name;
        private string luster;
        public override double Cost
        {
            get { return cost; }
            set { cost = value; }
        }
        public override double Carat
        {
            get { return carat; }
            set { carat = value; }
        }
        public override string Name
        {
            get { return name; }
            set { name = value; }
        }
        public override string Luster
        {
            get { return luster; }
            set { luster = value; }
        }
        public Emerald(double cost, double carat, string name, string luster)
        {
            this.carat = carat;
            this.cost = cost;
            this.name = name;
            this.luster = luster;
        }
    }

     class Obsidian : NotPrecious
    {
        private double cost;
        private double carat;
        private string name;
        private string origin;

        public override double Cost
        {
            get { return cost; }
            set { cost = value; }
        }
        public override double Carat
        {
            get { return carat; }
            set { carat = value; }
        }
        public override string Name
        {
            get { return name; }
            set { name = value; }
        }
        public override string Origin
        {
            get { return origin; }
            set { origin = value; }
        }

        public Obsidian(double cost, double carat, string name, string origin)
        {
            this.carat = carat;
            this.cost = cost;
            this.name = name;
            this.origin = origin;
        }
    }

     class Jasper : NotPrecious
    {
        private double cost;
        private double carat;
        private string name;
        private string origin;

        public override double Cost
        {
            get { return cost; }
            set { cost = value; }
        }
        public override double Carat
        {
            get { return carat; }
            set { carat = value; }
        }
        public override string Name
        {
            get { return name; }
            set { name = value; }
        }
        public override string Origin
        {
            get { return origin; }
            set { origin = value; }
        }

        public Jasper(double cost, double carat, string name, string origin)
        {
            this.carat = carat;
            this.cost = cost;
            this.name = name;
            this.origin = origin;
        }
    }


    //~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~
    //~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~
    abstract class CreatorPrecious
    {
        public abstract AbstractJewel FactoryMethod(double cost, double carat, string name, string luster);
    }

    abstract class CreatorNotPrecious
    {
        public abstract AbstractJewel FactoryMethod(double cost, double carat, string name, string origin);
    }

    class RubyCreator:CreatorPrecious
    {
        public override AbstractJewel FactoryMethod(double cost, double carat, string name, string luster)
        {
            return new Ruby(cost, carat, name, luster);
        }
    }

    class DiamondCreator : CreatorPrecious
    {
        public override AbstractJewel FactoryMethod(double cost, double carat, string name, string luster)
        {
            return new Diamond(cost, carat, name, luster);
        }
    }

    class EmeraldCreator : CreatorPrecious
    {
        public override AbstractJewel FactoryMethod(double cost, double carat, string name, string luster)
        {
            return new Emerald(cost, carat, name, luster);
        }
    }

    class ObsidianCreator : CreatorNotPrecious
    {
        public override AbstractJewel FactoryMethod(double cost, double carat, string name, string origin)
        {
            return new Obsidian(cost, carat, name, origin);
        }
    }

    class JasperCreator : CreatorNotPrecious
    {
        public override AbstractJewel FactoryMethod(double cost, double carat, string name, string origin)
        {
            return new Jasper(cost, carat, name, origin);
        }
    }
}



